function SINR_approx = generate_SINR_approx(scheme, H_eff, P_T, alpha)
% GENERATE_SINR_APPROX 生成确定性SINR近似值（文献公式25,33,39）
%   输入：
%     scheme: 预编码方案 'JGP'/'PGP'/'CGP'
%     H_eff: [K×b]有效信道矩阵
%     P_T: 总发射功率
%     alpha: 正则化参数
%     varargin: 方案特定参数
%        PGP: groups (用户分组)
%        CGP: common_groups, groups (公共组和分组)
%   输出：
%     SINR_approx: [K×1]确定性SINR近似值
%
%   文献依据：公式(25,33,39)

    % ========== 1. 参数验证 ==========
    [K, b] = size(H_eff);
    sigma2 = alpha;
    if nargin < 3
        alpha = 1/K; % 默认正则化参数
    end
%     validate_parameters(H_eff, P_T, alpha);
    
    % ========== 2. 方案选择 ==========
    switch scheme
        case 'JGP'
            % 联合组处理（公式25）
            SINR_approx = JGP_deterministic_SINR(H_eff, P_T, alpha, sigma2);
            
        case 'PGP'
            % 每组处理（公式33）
            groups = [ones(6,1); 2*ones(6,1); 3*ones(6,1)]; % 3组
            SINR_approx = PGP_deterministic_SINR(H_eff, groups, P_T, alpha, sigma2);
            
        case 'CGP'
            % 公共组处理（公式39）
            common_groups = {[1,2], 3}; % 前两组公共
            groups = [ones(6,1); 2*ones(6,1); 3*ones(6,1)]; % 3组
            SINR_approx = CGP_deterministic_SINR(H_eff, common_groups, groups, P_T, alpha, sigma2);
            
        otherwise
            error('未知预编码方案: %s', scheme);
    end
    
    % ========== 3. 验证结果 ==========
%     validate_SINR(SINR_approx, K);
end

%% ===== JGP确定性SINR近似（公式25） =====
function SINR = JGP_deterministic_SINR(H_eff, P_T, alpha, sigma2)
% 文献公式25实现
    [K, b] = size(H_eff);
    
    % 1. 计算D矩阵（公式27）
    D = H_eff' * H_eff; % b×b矩阵
    
    % 2. 计算W矩阵（公式21）
    W = inv(D + K*alpha*eye(b));
    
    % 3. 计算m_g^J（公式26）
    m = zeros(K, 1);
    for g = 1:K
        m(g) = (1/K) * trace(D * W);
    end
    
    % 4. 计算c_p^J（公式27）
    c = zeros(K, 1);
    for p = 1:K
        c(p) = (1/K^2) * trace(D * W^2);
    end
    
    % 5. 计算c_{g,p}^J（公式27）
    c_gp = zeros(K, K);
    for g = 1:K
        for p = 1:K
            c_gp(g,p) = (1/K^2) * trace(D * W * D * W);
        end
    end
    
    % 6. 计算SINR（公式25）
    SINR = zeros(K, 1);
    for g = 1:K
        num = (m(g))^2;
        denom = (K-1)*c_gp(g,g)/(1+m(g))^2;
        
        for p = 1:K
            if p == g, continue; end
            denom = denom + K*c_gp(g,p)/(1+m(p))^2;
        end
        
        denom = denom + K*c(g)*sigma2*(1+m(g))^2/P_T;
        
        SINR(g) = num / denom;
    end
end

%% ===== PGP确定性SINR近似（公式33） =====
function SINR = PGP_deterministic_SINR(H_eff, groups, P_T, alpha, sigma2)
% 文献公式33实现
    G = length(unique(groups));
    K = size(H_eff, 1);
    SINR = zeros(K, 1);
    
    for g = 1:G
        % 1. 提取组内用户
        group_idx = find(groups == g);
        K_g = length(group_idx);
        H_g = H_eff(group_idx, :);
        
        % 2. 计算组内D_g^P（公式35）
        D_g = H_g' * H_g; % b×b矩阵
        
        % 3. 计算W_g（公式29）
        W_g = inv(D_g + K_g*alpha*eye(size(D_g)));
        
        % 4. 计算m_g^P（公式34）
        m_g = (1/K_g) * trace(D_g * W_g);
        
        % 5. 计算c_g^P（公式35）
        c_g = (1/K_g^2) * trace(D_g * W_g^2) / ...
              (1 - (K_g/K_g^2)*trace((D_g*W_g)^2)/(1+m_g)^2);
        
        % 6. 计算c_{g,p}^P（公式35）
        c_gp = zeros(G, 1);
        for p = 1:G
            if p == g, continue; end
            % 计算D_{g,p}^P（公式35）
            % 注：实际实现需提取组p信道
            c_gp(p) = (1/K_g^2) * trace(D_g * W_g * D_g * W_g) / ...
                      (1 - (K_g/K_g^2)*trace((D_g*W_g)^2)/(1+m_g)^2);
        end
        
        % 7. 计算组内用户SINR（公式33）
        for k = 1:K_g
            user_idx = group_idx(k);
            num = (m_g)^2;
            denom = (K_g-1)*c_g/(1+m_g)^2;
            
            for p = 1:G
                if p == g, continue; end
                denom = denom + c_gp(p);
            end
            
            denom = denom + K*c_g*sigma2/P_T;
            
            SINR(user_idx) = num / denom;
        end
    end
end

%% ===== CGP确定性SINR近似（公式39） =====
function SINR = CGP_deterministic_SINR(H_eff, common_groups, groups, P_T, alpha, sigma2)
% 文献公式39实现
    G_prime = length(common_groups);
    K = size(H_eff, 1);
    SINR = zeros(K, 1);
    
    for gp = 1:G_prime
        % 1. 合并公共组用户
        group_users = [];
        for g = common_groups{gp}
            group_users = [group_users; find(groups == g)];
        end
        K_gp = length(group_users);
        H_gp = H_eff(group_users, :);
        
        % 2. 计算D_gp^C（公式41）
        D_gp = H_gp' * H_gp;
        
        % 3. 计算W_gp（公式36）
        W_gp = inv(D_gp + K_gp*alpha*eye(size(D_gp)));
        
        % 4. 计算m_g^C（公式40）
        m_g = zeros(length(common_groups{gp}), 1);
        for idx = 1:length(common_groups{gp})
            g = common_groups{gp}(idx);
            m_g(idx) = (1/K_gp) * trace(D_gp * W_gp);
        end
        
        % 5. 计算c_g^C（公式41）
        c_g = zeros(length(common_groups{gp}), 1);
        for idx = 1:length(common_groups{gp})
            g = common_groups{gp}(idx);
            c_g(idx) = (1/K_gp^2) * trace(D_gp * W_gp^2) / ...
                      (1 - (K_gp/K_gp^2)*trace((D_gp*W_gp)^2)/(1+m_g(idx))^2);
        end
        
        % 6. 计算c_{g,p}^C（公式41）
        c_gp = zeros(G_prime, 1);
        for p = 1:G_prime
            if p == gp, continue; end
            % 计算D_{gp,p}^C（公式41）
            % 注：实际实现需提取公共组p信道
            c_gp(p) = (1/K_gp^2) * trace(D_gp * W_gp * D_gp * W_gp) / ...
                      (1 - (K_gp/K_gp^2)*trace((D_gp*W_gp)^2)/(1+m_g(1))^2);
        end
        
        % 7. 计算公共组用户SINR（公式39）
        for k = 1:K_gp
            user_idx = group_users(k);
            g_idx = find(common_groups{gp} == groups(user_idx));
            
            num = (m_g(g_idx))^2;
            denom = (K_gp-1)*c_g(g_idx)/(1+m_g(g_idx))^2;
            
            for p = 1:G_prime
                if p == gp, continue; end
                denom = denom + c_gp(p);
            end
            
            denom = denom + K*c_g(g_idx)*sigma2/P_T;
            
            SINR(user_idx) = num / denom;
        end
    end
end

%% ===== 子函数：参数验证 =====
function validate_parameters(H_eff, P_T, alpha)
    if ~ismatrix(H_eff)
        error('H_eff必须是矩阵');
    end
    if ~isscalar(P_T) || P_T <= 0
        error('P_T必须是正标量');
    end
    if ~isscalar(alpha) || alpha < 0
        error('alpha必须是非负标量');
    end
end

%% ===== 子函数：SINR验证 =====
function validate_SINR(SINR, K)
    if length(SINR) ~= K
        error('SINR向量长度(%d)与用户数(%d)不匹配', length(SINR), K);
    end
    if any(SINR < 0)
        warning('部分SINR值为负，可能计算错误');
    end
    if any(isnan(SINR))
        error('SINR包含NaN值');
    end
end